#| GTK Application Templage (Guile Scheme version). |#
(import (prefix (gi) gi:)
        ;; function of gi repository can be found at:
        ;; https://spk121.github.io/guile-gi/Typelib-Introspection.html
        (prefix (gi repository) gir:))

;; (use-typelibs ("GLib" "2.0")
;;               ("Gio" "2.0")
;;               ("Gtk" "3.0"))

;; Load Gio in version 2.0, but only, if it is not already
;; loaded.
(gir:require "Gio" "2.0")
;; Load GTK in version 3.0, but only, if it is not already
;; loaded.
(gir:require "Gtk" "3.0")

;; After having loaded the Gio and Gtk libraries, generate
;; bindings for the specified types.

;; (gir:load-by-name "Gio" "ActionMap")  ; add-action
(gir:load-by-name "Gio" "Application")  ; activate, run
;; (gir:load-by-name "Gio" "SimpleAction")
(gir:load-by-name "Gtk" "Application")
(gir:load-by-name "Gtk" "ApplicationWindow")
(gir:load-by-name "Gtk" "Button")
(gir:load-by-name "Gtk" "ButtonBox")
;; (gir:load-by-name "Gtk" "ApplicationFlags")  ; not valid
;; (gir:load-by-name "Gtk" "Builder")
(gir:load-by-name "Gtk" "init")
;; (gir:load-by-name "Gtk" "MenuButton")  ; set-popover
;; (gir:load-by-name "Gtk" "Popover")
(gir:load-by-name "Gtk" "Widget")  ; show-all


;; initialize GTK
(init!)


(define app:activate
  (λ (app)
    ;; ApplicationWindow has a constructur.
    (define window
      (gi:make <GtkApplicationWindow>
        ;; Set some values for the window.
        #:application app
        #:default-height 200
        #:default-width 200
        #:title "Example"))

    ;; (set-title window "Example")
    ;; (set-default-size window 200 200)

    ;; ButtonBox has a constructor
    ;; button-box:new. button-box:new expects an orientation
    ;; for the buttons to be put into the box.
    (define button-box
      (gi:make <GtkButtonBox>
        #:parent window))

    ;; Button has more than one constructor. Here the one is
    ;; used, which takes a string as a label.
    (define button
      (gi:make <GtkButton>
        #:parent button-box
        #:label "Exit"))

    ;; Define an action performed, when the button is
    ;; clicked.
    (gi:connect button clicked (λ args (destroy window)))

    ;; Next widgets are being added to other widgets and
    ;; ultimately to the window. This is done using the (add
    ;; ...) function.

    ;; Add the ButtonBox to the ApplicationWindow.
    ;; (add window button-box)
    ;; Add the Button to the ButtonBox.
    ;; (add button-box button)
    ;; The window needs to be added to the application.
    ;; (add-window app window)

    ;; Show the windows of the application.
    (show-all window)))


(define main
  (λ ()
    ;; Call Gtk's application:new to create a new
    ;; <GtkApplication>
    (let ([app (gi:make <GtkApplication> #:application-id "org.gtk.example")
           #;(application:new
                "org.gtk.example"
                ;; Application flags govern how the application
                ;; behaves. See more at:
                ;; https://docs.gtk.org/gio/flags.ApplicationFlags.html.
                (list->application-flags '(flags-none)))])
      (gi:connect app activate app:activate)
      (exit
       ;; Call application:run.  If there are no arguments in
       ;; the command line args, this will send the `activate'
       ;; signal.
       (run app (command-line))))))


(main)
